package com.thread;

import net.sf.jsqlparser.statement.execute.Execute;

import java.util.concurrent.*;

public class ThreadTest {
    public static ExecutorService executor = Executors.newFixedThreadPool(10);//线程池里有10个线程等待异步任务

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main方法...start启动..");
 /*       CompletableFuture.runAsync(()->{
            System.out.println("当前线程"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果"+i);
        },executor);*/
//        CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程" + Thread.currentThread().getId());
//            int i = 10 / 0;
//            System.out.println("运行结果" + i);
//            return i;
//        }, executor).whenComplete((res,excption)->{ //前面是结果Result 后面是异常Exception
//            System.out.println("异步任务完成了");
//            System.out.println("结果是"+ res);
//            System.out.println("异常是"+ excption);
//        }).exceptionally(throwable -> {
//            //感知异常，返回默认值
//            return 10;
//        });
//        CompletableFuture<Integer> handle = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程" + Thread.currentThread().getId());
//            int i = 10 / 0;
//            System.out.println("运行结果" + i);
//            return i;
//        }, executor).handle((res, excption) -> {
//            //方法执行完成后的执行处理
//            if (res!=null){
//                return res*2;
//            }
//            if (excption!=null){
//                return 0;
//            }
//            return 0;
//        });

        /**
         * 线程串行化，
         * 1.thenRun不能获取到上一步的执行结果
         * .thenRunAsync(() -> {
         *             System.out.println("任务2启动了");
         *         }, executor)
         * 2.thenAcceptAsync能接受上一步结果，无返回值
         * .thenAcceptAsync((res)->{
         *              System.out.println("任务2启动了"+res);
         *          })
         * 3.thenApplyAsync接受上一步结果，有返回值
         */
       /* CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
            System.out.println("当前线程" + Thread.currentThread().getId());
            int i = 10 / 5;
            System.out.println("运行结果" + i);
            return i;
        }, executor).thenApplyAsync(res -> {
            System.out.println("线程2启动了" + res);
            System.out.println(2+res);
            return "Hello" + 2;
        }, executor);*/


        /**
         * 俩个都完成 俩任务组合
         */
//        CompletableFuture<Object> future01 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务01线程启动了" + Thread.currentThread().getId());
//            int i = 10 / 5;
//            System.out.println("任务01线程结束了" + i);
//            return i;
//        }, executor);
//
//        CompletableFuture<Object> future02 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务02线程启动了" + Thread.currentThread().getId());
//
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("任务02线程结束了");
//            return "hello";
//        }, executor);

//        future01.runAfterBothAsync(future02,()->{
//            System.out.println("任务03开始");
//        },executor);  不能感知结果

//        future01.thenAcceptBothAsync(future02,(res01,res02)->{
//            System.out.println("任务03开始....之前的结果为"+res01+"和"+res02);
//        },executor);

       /* CompletableFuture<String> future = future01.thenCombineAsync(future02, (f1, f2) -> {
            return f1 + ":" + f2 + "-> hello";
        }, executor);*/

        /**
         * 1个完成 就执行任务 3 俩任务组合
         */
//        future01.runAfterEitherAsync(future02,()->{
//            System.out.println("任务03开始");
//        },executor); //不感知结果，自己没有返回值
//        future01.acceptEitherAsync(future02,(res)->{
//            System.out.println("任务03开始,,之前结果是"+res);
//        },executor); //感知结果，没有返回值
//        CompletableFuture<String> future = future01.applyToEitherAsync(future02, (res) -> {
//            System.out.println("任务03开始了，之前结果是"+res);
//            return res.toString() + "-> hahaha";
//        }, executor);

        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品图片信息");
            return "Hello.jpg";
        },executor);
        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            System.out.println("查询商品属性信息");
            return "黑色+256G";
        },executor);
        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("查询商品介绍");
            return "华为";
        },executor);

//        futureImg.get();
//        futureAttr.get();
//        futureDesc.get(); 阻塞式等待，太麻烦了
        CompletableFuture<Void> allOf = CompletableFuture.allOf(futureImg, futureAttr, futureDesc);
        allOf.get();//等待3个都做完
//        allOf.join();//线程插入进来，等待都做完

        System.out.println("main方法...end结束.." );
        System.out.println(futureImg.get()+futureAttr.get()+futureDesc.get());
    }
    public void Thread(String[] args) throws ExecutionException,InterruptedException {


//        service.excute(new Thread01());

        /**
         * 1.创建线程池，准备好核心进程 --5
         * 2.core满了，就将再进来的任务放入阻塞队列中，空闲的core就会自己去阻塞队列中获取任务执行
         * 3.阻塞队列满了，就直接开新线程执行，最大开导max的数量
         * 4.max满了，就用拒绝任务
         * 5.max执行完成，有很多空闲了， 200-5 = 195 ，在指定的存货时间以后，keepAliveTime 释放max-core线程
         * LinkedBlockingDeque 默认是Integer的最大值 内存不够
         * threadFactory工厂，用默认
         * handler：拒绝策略 不想抛弃，继续执行，CallerRunsPolity
         */
//        ThreadPoolExecutor pool = new ThreadPoolExecutor(5
//                ,200
//                ,10
//                , TimeUnit.SECONDS
//                ,new LinkedBlockingDeque<>(100000)
//                ,Executors.defaultThreadFactory()
//                ,new ThreadPoolExecutor.AbortPolicy());
//        pool.execute(new Thread01());
//        Executors.newFixedThreadPool(); 固定大小 ,core等于最大，都不可回收
//        Executors.newCachedThreadPool(); core是0 ，所有都可回收
//        Executors.newScheduledThreadPool() 定时任务的线程池
//        Executors.newSingleThreadExecutor(); 单线程的线程池，后台从队列里获取任务，挨个执行
//        System.out.println("main方法...end结束..");
    }

   /* public static class Thread01 extends Thread{
        @Override
        public void run() {
            System.out.println("当前线程"+Thread.currentThread().getId());
            int i = 10/2;
            System.out.println("运行结果"+i);
        }
    }*/
}
